package br.com.datasun.biblioteca.ui.components;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.swing.table.AbstractTableModel;

import br.com.datasun.biblioteca.entities.Biblioteca;
import br.com.datasun.biblioteca.entities.Cidade;
import br.com.datasun.biblioteca.entities.Documento;
import br.com.datasun.biblioteca.entities.Endereco;
import br.com.datasun.biblioteca.entities.Estado;
import br.com.datasun.biblioteca.entities.PessoaFisica;

public class ClienteTableModel extends AbstractTableModel{
	private static final long serialVersionUID = 1L;
	
	/**
	 * Lista que cont�m os PessoaFisicas a serem apresentados na tabela
	 */
	private List<PessoaFisica> pessoaFisicas;
	private List<String> colunas;
	public final int COLUNA_NOME = 0;
	public final int COLUNA_DT_NASCIMENTO = 1;
	public final int COLUNA_CPF = 2;
	public final int COLUNA_CIDADE = 3;
	public final int COLUNA_ATIVO = 4;
	private SimpleDateFormat sdf_ddmmyyyy = new SimpleDateFormat("dd/MM/yyyy");
	
	public ClienteTableModel(List<PessoaFisica> PessoaFisicas){
		this.pessoaFisicas = PessoaFisicas;
		if(this.pessoaFisicas == null){
			this.pessoaFisicas = new ArrayList<PessoaFisica>();
		}
		/**
		 * Inicializa a lista que cont�m os nomes das colunas da tabela
		 */
		colunas = new ArrayList<String>();
		colunas.add("Nome");
		colunas.add("Dt. Nasc.");
		colunas.add("CPF");
		colunas.add("Cidade");
		colunas.add("Ativo");
	}
	public ClienteTableModel(){
		if(this.pessoaFisicas == null){
			this.pessoaFisicas = new ArrayList<PessoaFisica>();
		}
		/**
		 * Inicializa a lista que cont�m os nomes das colunas da tabela
		 */
		colunas = new ArrayList<String>();
		colunas.add("Nome");
		colunas.add("Dt. Nasc.");
		colunas.add("CPF");
		colunas.add("Cidade");
		colunas.add("Ativo");
	}
	
	/**
	 * Obt�m o n�mero de colunas da tabela
	 */
	public int getColumnCount() {
		return colunas.size();
	}
	/**
	 * Obtem o n�mero de linhas da tabela
	 */
	public int getRowCount() {
		return pessoaFisicas.size();
	}
	/**
	 * Obt�m o valor contido na linha representada por indiceLinha e coluna representada por indiceColuna. 
	 * @param indiceLinha - indice da linha
	 * @param indiceColuna - indice da coluna
	 */
	public Object getValueAt(int indiceLinha, int indiceColuna) {
		String result = null;
		PessoaFisica pessoaFisica = null;
		pessoaFisica = pessoaFisicas.get(indiceLinha); //obt�m o PessoaFisica da linha
		switch (indiceColuna) {
		case COLUNA_NOME:
			result = pessoaFisica.getNome();
			break;
		case COLUNA_DT_NASCIMENTO:
			if(pessoaFisica.getDataNascimento() !=null){
				result = sdf_ddmmyyyy.format(pessoaFisica.getDataNascimento());
			}
			break;
		case COLUNA_CPF:
			Documento documento = pessoaFisica.getCPF();
			if(documento!= null){
				result = documento.getNumero();
			}
			break;
		case COLUNA_CIDADE:
			Endereco endereco = pessoaFisica.getEndereco();
			if(endereco != null && endereco.getCidade() != null){
				Cidade cidade = endereco.getCidade();
				Estado estado = cidade.getEstado();
				StringBuilder sb = new StringBuilder();
				sb.append(cidade.getNome());
				sb.append("/");
				sb.append(estado.getSigla());
				result = sb.toString();
			}
			break;
		case COLUNA_ATIVO:
			result = pessoaFisica.isAtivo()? "Sim" : "N�o";
			break;
		}
		return result;
		
	}
	/**
	 * Obt�m o t�tulo da coluna
	 */
	public String getColumnName(int column) {
		return colunas.get(column);
	}
	/**
	 * Obt�m o tipo de objeto que a coluna aceita
	 */
	public Class<?> getColumnClass(int columnIndex) {
		Class result = null;
		switch (columnIndex) {
		case COLUNA_NOME:
			result = String.class;
			break;
		case COLUNA_DT_NASCIMENTO:
			result = String.class;
			break;
		case COLUNA_CPF:
			result = String.class;
			break;
		case COLUNA_CIDADE:
			result = String.class;
			break;
		case COLUNA_ATIVO:
			result = String.class;
			break;
		}
		return result;
	}
	/**
	 * Altera o valor da coluna representada por indiceColuna e linha representada por indiceLinha.
	 */
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
		//nenhuma celula � edit�vel

	}

	@Override
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		return false; //nenhuma c�lula � edit�vel
	}
	
	public void inserir(PessoaFisica PessoaFisica){
		pessoaFisicas.add(PessoaFisica);
		fireTableStructureChanged(); //avisa listeners que a estrutura da tabela mudou - faz repaint
	}

	public PessoaFisica remover(int rowIndex){
		PessoaFisica pessoaFisica = null;
		if(rowIndex >= 0 && !pessoaFisicas.isEmpty()){
			pessoaFisica = pessoaFisicas.remove(rowIndex);
			fireTableStructureChanged();//avisa listeners que a estrutura da tabela mudou - faz repaint
		}
		return pessoaFisica;
	}
	
	
	public void remover (PessoaFisica pessoaFisica){
		pessoaFisicas.remove(pessoaFisica);
		fireTableStructureChanged();
	}
	
	public PessoaFisica getPessoaFisicaDe(int rowIndex){
		PessoaFisica pessoaFisica = null;
		if(rowIndex >= 0 && !pessoaFisicas.isEmpty()){
			pessoaFisica = pessoaFisicas.get(rowIndex);
		}
		return pessoaFisica;
	}
	/**
	 * Substitui o objeto PessoaFisica existente no indice fornecido pelo PessoaFisica fornecido
	 * @param pessoaFisica
	 * @param indiceLinha
	 */
	public void atualizarPessoaFisica(PessoaFisica pessoaFisica, int indiceLinha){
		pessoaFisicas.set(indiceLinha, pessoaFisica);
		fireTableRowsUpdated(indiceLinha, indiceLinha);
	}
	
	public void atualizarPessoaFisica(PessoaFisica pessoaFisica){
		int indiceLinha = pessoaFisicas.indexOf(pessoaFisica);
		pessoaFisicas.set(indiceLinha, pessoaFisica);
		fireTableRowsUpdated(indiceLinha, indiceLinha);
	}	
	/**
	 * Verifica se o PessoaFisica fornecido existe no table model
	 * @param pessoaFisica
	 * @return
	 */
	public boolean existe(PessoaFisica pessoaFisica){
		boolean result = false;
		if(!pessoaFisicas.isEmpty()){
			result = pessoaFisicas.contains(pessoaFisica);
		}
		return result;
	}
	public List<PessoaFisica> getPessoaFisicas(){
		return this.pessoaFisicas;
	}
	public void setPessoasFisicas(List<PessoaFisica> pessoasFisicas){
		this.pessoaFisicas = pessoasFisicas;
		fireTableStructureChanged();
	}
	
	

}
